require "Common/EnumConst"
require "Battle/Entity/Entity"
require "Battle/FightEntity"
require "Battle/Entity/PetEntity"
require "Battle/Manager/SpineEffectManager"
require "Battle/BattleScene"

---@class EntityAiManager
EntityAiManager = {};
local this = EntityAiManager;
local defaultFrame = EnumConst.FIGHT_FRAME / EnumConst.THOUSANDTH

local cacheVec1 = Vector3(0, 0, 0)
local cacheVec2 = Vector3(0, 0, 0)

--丽姬娅 【1】 ： 1立即切换 2 持续时间结束后切换(参数） 3 若有duration则执行完切换否则直接切换
--【1】 ：2 [状态1 ，状态2]
--【2】 ：【1】 2 参数[持续时间(毫秒)||持续时间最小  ,随机时间最大]
--状态强行切换 不受状态机影响
local SHOW_AI = {
    [0] = { { 11 } },
    [2] = { { 11, 13 } },
    [9] = { { 11 } },
    [10] = { { 13 } },
    [13] = { { 11 }, { 1000, 2000 } },
    [11] = { { 2, 13 } },

};
local AI_MODEL_ID = {
    [611] = 1;
}

function EntityAiManager.init()

end

function EntityAiManager.destroy()

end

function EntityAiManager.updateAi(entity, deltaTime)
    if AI_MODEL_ID[tonumber(entity.partnerModelId)] and FightManager.entranceFinish then
        --更新状态机状态
        if entity.aniStateNew ~= entity.aniState then
            if entity.aniStateNew == Config.AnimationState.START then
                entity.duration = entity:playAction(Config.AnimationStateName.START, false);
            elseif entity.aniStateNew == Config.AnimationState.RUN then
                entity.duration = 0;
                entity:playAction(Config.AnimationStateName.RUN);
            elseif entity.aniStateNew == Config.AnimationState.WALK then
                entity.duration = 0;
                entity:playAction(Config.AnimationStateName.WALK);
            elseif entity.aniStateNew == Config.AnimationState.ATTACK then
                entity.duration = entity:playAnimation(entity.actionName, true, -1, true);
                entity.duration = 0;
                --logMy(entity.name,'播放攻击',entity.duration,entity.isLoop,FightManager.frame)
            elseif entity.aniStateNew == Config.AnimationState.DEAD then
                entity.showDead = true;
                entity.isDeading = true;
                entity.duration = 1.167;
                entity:playAnimation("weak", false, -1, true);
            elseif entity.aniStateNew == Config.AnimationState.VICTORY then
                entity.timeScale = 1;--胜利动作不加速
                entity.duration = entity:playAction(Config.AnimationStateName.VICTORY, false);
            elseif entity.aniStateNew == Config.AnimationState.IDLE then
                entity:playAction(Config.AnimationStateName.IDLE);
            else
                logMy("动画状态机 未处理状态", entity.aniStateNew)
            end
            entity.aniState = entity.aniStateNew;

        else
            if entity.aniStateNew == Config.AnimationState.IDLE then
                entity:onUpdateBar();
            end
        end

        --每个循环动画状态单独控制细节
        if entity.aniState == Config.AnimationState.WALK then
            cacheVec1.x, cacheVec1.y, cacheVec1.z = Util.Lua_GetLocalPositionXYZ(entity.roleObj, 0, 0, 0);
            entity.moveDirection = Vector3.Normalize(entity.moveEnd - cacheVec1);
            if Vector3.Distance(entity.moveEnd, cacheVec1) <= deltaTime * entity.moveSpeed * entity.timeScale then
                Util.Lua_SetLocalPositionXYZ(entity.roleObj, entity.moveEnd.x, entity.moveEnd.y, entity.moveEnd.z);
                this.doNewActionMap(entity.aniState, entity)
            else
                Vec3Mul(entity.moveDirection, deltaTime * entity.moveSpeed * entity.timeScale, cacheVec2);
                Vec3Add(cacheVec1, cacheVec2, cacheVec2);
                entity:revisePosition(cacheVec2);
            end
            --elseif entity.moveType == EnumConst.MoveType.Direction then
            --    Vec3Mul(entity.moveDirection, deltaTime * entity.moveSpeed * entity.timeScale, cacheVec2);
            --    Vec3Add(cacheVec1, cacheVec2, cacheVec2);
            --    entity:revisePosition(cacheVec2);
            --end

            local flip = false;
            if entity.moveTarget ~= nil then
                flip = getRoleFlip(entity, entity.moveTarget);
            else
                if entity.moveDirection.x > 0 then
                    flip = false;
                elseif entity.moveDirection.x == 0 then
                    flip = entity.flip;
                else
                    flip = true;
                end
            end
            entity:setFlip(flip);
            entity:onUpdateBar();
        elseif entity.aniState == Config.AnimationState.ATTACK then
            local flip = false;
            local target = FightManager.getEntityByModel("610", entity.teamIndex);
            if target ~= nil then
                flip = getRoleFlip(entity, target);
            else
                if entity.moveDirection.x > 0 then
                    flip = false;
                elseif entity.moveDirection.x == 0 then
                    flip = entity.flip;
                else
                    flip = true;
                end
            end
            entity:setFlip(flip);

        elseif entity.aniState == Config.AnimationState.RUN then
            cacheVec1.x, cacheVec1.y, cacheVec1.z = Util.Lua_GetLocalPositionXYZ(entity.roleObj, 0, 0, 0);
            entity.moveDirection = Vector3.Normalize(entity.moveEnd - cacheVec1);
            local tempPos = cacheVec1 + entity.moveDirection * deltaTime * entity.speedRun * entity.timeScale;
            Util.Lua_SetLocalPositionXYZ(entity.roleObj, tempPos.x, tempPos.y, tempPos.z)
            local flip = false;
            if entity.moveTarget ~= nil then
                flip = getRoleFlip(entity, entity.moveTarget);
            else
                if entity.moveDirection.x > 0 then
                    flip = false;
                elseif entity.moveDirection.x == 0 then
                    flip = entity.flip;
                else
                    flip = true;
                end
            end
            entity:setFlip(flip);
            --entity:onUpdateBar();
        end

        --状态结束 切回idleBattle
        if entity.duration > 0 or (entity.aniState == Config.AnimationState.IDLE and (entity.duration == 0 or (entity.teamIndex == 2 and entity.duration < 0))) then
            entity.duration = entity.duration - deltaTime;
            if entity.duration <= 0 then

                if entity.isDeading then
                    entity:onDeadEnd();
                else
                this.doNewActionMap(entity.aniState, entity)
                end
            end
        end
        if entity.delayCallFunc then
            --强制死亡倒计时；
            entity.delayCallDuration = entity.delayCallDuration - delayDeadTime;
            if entity.delayCallDuration <= 0 then
                entity.delayCallFunc();
            end
        end

        return true;
    else
        return false;
    end

end
function EntityAiManager.setAiAniState(state, entity, actionName, isClear)
    if AI_MODEL_ID[tonumber(entity.partnerModelId)] then
        math.randomseed(tostring(os.time()):reverse():sub(1, 7))
        if actionName == "fidle" and state == Config.AnimationState.ATTACK then
            state = Config.AnimationState.IDLE;
        end
        local actionMap = SHOW_AI[state];
        if state == Config.AnimationState.WALK then
            local maxPos = decodeJsonStrToTabel(G.dataTable["t_global"]["54"].f_string_value);--屏幕左上角到右下角最大位置
            local posX = math.random(304.5, 311.275);
            local posY = 283.5;
            if entity.teamIndex == 2 then
                posX = math.random(311, 303.2);
                posY = 298.2;
            end
            cacheVec1.x, cacheVec1.y, cacheVec1.z = Util.Lua_GetLocalPositionXYZ(entity.roleObj, 0, 0, 0);
            if entity.teamIndex == 2 and cacheVec1.z < posY or entity.teamIndex == 1 and cacheVec1.z > posY then
                posX = cacheVec1.x;
            end

            local pos = Vector3.New(posX, cacheVec1.y, posY)
            entity.moveEnd = pos;
        end

        if actionMap and actionMap[2] then
            entity.duration = math.random(actionMap[2][1], actionMap[2][2]) / 1000
        end
        if entity.aniStateNew == Config.AnimationState.DEAD then
            return true;
        end
        entity.aniStateNew = state;
        if actionName then
            entity.actionName = actionName;
        end
        return true;
    else
        return false;
    end

end
--下一行动指令
function EntityAiManager.doNewActionMap(state, entity)
    if FightManager.gameEnd then
        return ;
    end
    math.randomseed(tostring(os.time()):reverse():sub(1, 7))
    local actionMap = SHOW_AI[state];
    local newState = actionMap[1][1];
    if table.getn(actionMap[1]) > 1 then
        newState = actionMap[1][math.floor(math.random(1, table.getn(actionMap[1])) + 0.5)];
    end

    this.setAiAniState(newState, entity);
end

function EntityAiManager.checkAIRole(entity)
    if AI_MODEL_ID[tonumber(entity.partnerModelId)] then
        return true;
    end
    return false;
end